package edu.isquen.util.factory;

import java.lang.reflect.Method;

import edu.isquen.core.base.dao.IBaseDAO;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class DaoFactory implements MethodInterceptor {

	private static Enhancer enhancer = new Enhancer();

	public static IBaseDAO<?> getDao(String voClassName) throws Exception {
		IBaseDAO<?> dao = null;

		if (voClassName.indexOf(".model.") > 0) {
			String factoryClassName = getDaoClassName(voClassName);

			Class<?> factoryClazz = Class.forName(factoryClassName);

			DaoFactory factory = new DaoFactory();

			Class<?>[] argtypes = new Class[1];
			argtypes[0] = String.class;

			Object[] args = new Object[1];
			args[0] = voClassName;
			try{
				dao = (IBaseDAO<?>) factoryClazz.getConstructor(argtypes)
						.newInstance(args);
			}catch (Exception e) {
				dao = (IBaseDAO<?>) factory.getInstrumentedClass(new Class<?>[] {},
						factoryClazz, argtypes, args);
			}
		}

		return dao;
	}

	private static String getDaoClassName(String voClassName) {
		String packageName = voClassName.substring(0, voClassName
				.lastIndexOf(".model."))
				+ ".dao";
		String className = voClassName.substring(voClassName
				.lastIndexOf(".model.") + 7, voClassName.length());
		// className = className.replaceAll("VO", "");

		String daoClassName = packageName + "." + className + "DAO";
		return daoClassName;
	}

	@SuppressWarnings("rawtypes")
	public Object getInstrumentedClass(Class[] iclzs, Class clz,
			Class[] argtypes, Object[] args) {

		enhancer.setInterfaces(iclzs);
		enhancer.setSuperclass(clz);
		enhancer.setCallback((Callback) this);

		return enhancer.create(argtypes, args);
	}

	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		// TODO Auto-generated method stub
		return null;
	}

}
